package org.massi.imslp.query;


import java.text.MessageFormat;

import org.apache.commons.lang.StringUtils;


/**
 * Implementation of {@link IQueryParameters}, to hold composer, work title and opus number. Uses
 * the builder pattern to create instances.
 */
public class QueryParameters implements IQueryParameters
{
	/**
	 * wild-card for 'like' queries
	 */
	private static final String LIKE = "*";

	/**
	 * composer name
	 */
	private final String composer;

	/**
	 * opus number
	 */
	private final String opusNumber;

	/**
	 * work title (optional)
	 */
	private final String workTitle;


	/**
	 * Create a new instance with composer, opus number and work title
	 * 
	 * @param composer
	 * @param opusNumber
	 * @param workTitle
	 */
	private QueryParameters(final String composer, final String opusNumber, final String workTitle)
	{
		super();
		this.composer = composer;
		this.opusNumber = opusNumber;
		this.workTitle = workTitle;
	}


	/**
	 * Use the Builder pattern to create instances of {@link QueryParameters}: it mimics the
	 * structure of {@link QueryParameters} and allow creation using the {@link #build()} method.
	 * Values can be set using the {@link #composer(String)}, {@link #opusNumber(String)} and
	 * {@link #workTitle(String)} methods
	 */
	public static class Builder
	{

		/**
		 * composer name
		 */
		private String composer;

		/**
		 * opus number
		 */
		private String opusNumber;

		/**
		 * 
		 */
		private String workTitle;


		/**
		 * Set the composer and return the builder instance
		 * 
		 * @param string
		 * @return the builder instance
		 */
		public Builder composer(final String string)
		{
			this.composer = string;
			return this;
		}


		/**
		 * Set the opus number and return builder instance
		 * 
		 * @param string
		 * @return the builder instance
		 */
		public Builder opusNumber(final String string)
		{
			this.opusNumber = string;
			return this;
		}


		/**
		 * Set the work title and return the builder instance
		 * 
		 * @param string
		 * @return the builder instance
		 */
		public Builder workTitle(final String string)
		{
			this.workTitle = string;
			return this;
		}


		/**
		 * Create a new instance of {@link QueryParameters}
		 * 
		 * @return a new instance of {@link IQueryParameters}
		 */
		public IQueryParameters build()
		{
			return new QueryParameters(this.composer, this.opusNumber, this.workTitle);
		}


		/*
		 * (non-Javadoc)
		 * 
		 * @see java.lang.Object#toString()
		 */
		@Override
		public String toString()
		{
			return "Builder [composer=" + this.composer + ", opusNumber=" + this.opusNumber + ", workTitle="
					+ this.workTitle + "]";
		}

	}


	/*
	 * (non-Javadoc)
	 * 
	 * @see org.massi.imslp.query.IQueryParameters#toQueryString()
	 */
	@Override
	public String toQueryString()
	{
		return toString();
	}


	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString()
	{
		// pattern like: <composer>*<opusNumber>*<workTitle> (Beethoven*Op.127*Quartet)
		// using the actual value or replacing with a wild-card
		final String pattern = "{0}*{1}*{2}";
		return MessageFormat.format(pattern, getQueryParameter(this.composer), getQueryParameter(this.opusNumber),
				getQueryParameter(this.workTitle));
	}


	/**
	 * Normalise a parameter value, returning a wild-card '*' if the given string is null or empty
	 * 
	 * @param parameterValue the parameter value to normalise
	 * @return trimmed value or '*' is the value is blank
	 * @see StringUtils#isBlank(String)
	 */
	private String getQueryParameter(final String parameterValue)
	{
		return StringUtils.isBlank(parameterValue) ? LIKE : parameterValue.trim();
	}
}
